package com.oa.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.joneying.common.annotation.CommonService;
import com.joneying.common.web.response.Resp;
import com.oa.core.PageResult;
import com.oa.core.constant.Constant;
import com.oa.core.exception.BusinessException;
import com.oa.core.exception.DataIsEmptyException;
import com.oa.system.dto.PostAddDTO;
import com.oa.system.dto.PostListDTO;
import com.oa.system.dto.PostUpdateDTO;
import com.oa.system.entity.Permission;
import com.oa.system.entity.Post;
import com.oa.system.entity.PostPermission;
import com.oa.system.entity.User;
import com.oa.system.mapper.PermissionMapper;
import com.oa.system.mapper.PostMapper;
import com.oa.system.mapper.PostPermissionMapper;
import com.oa.system.service.IPermissionService;
import com.oa.system.service.IPostPermissionService;
import com.oa.system.service.IPostService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.oa.system.service.IUserService;
import com.oa.system.vo.PermissionVO;
import com.oa.system.vo.PostDetailsVO;
import com.oa.system.vo.PostListVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 岗位表 服务实现类
 * </p>
 *
 * @author syb123
 * @since 2019-01-29
 */
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements IPostService {

    private final PostMapper postMapper;
    private final PostPermissionMapper postPermissionMapper;
    private final IPostPermissionService postPermissionService;
    private final PermissionMapper permissionMapper;
    private final IUserService userService;

    @Autowired
    public PostServiceImpl(PostMapper postMapper, PostPermissionMapper postPermissionMapper, IPostPermissionService postPermissionService, PermissionMapper permissionMapper, IUserService userService) {
        this.postMapper = postMapper;
        this.postPermissionMapper = postPermissionMapper;
        this.postPermissionService = postPermissionService;
        this.permissionMapper = permissionMapper;
        this.userService = userService;
    }

    @Autowired
    private IPermissionService permissionService;

    /**
     * 新增岗位
     *
     * @param postAddDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp addPost(PostAddDTO postAddDTO) throws BusinessException {

        if(selectCount(new EntityWrapper<Post>().eq("post_name", postAddDTO.getPostName()).eq("department_id", postAddDTO.getDepartmentId())) > 0){
            return new Resp<String>().failure("岗位名称重复");
        }

        Post post = new Post();

        BeanUtils.copyProperties(postAddDTO, post);

        post.setCreateTime(new Date());

        try {
            insert(post);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("添加岗位失败!");
        }

        //添加岗位权限
        if (!StringUtils.isEmpty(postAddDTO.getPermissionIds())) {
            List<PostPermission> postPermissionList = new ArrayList<>();
            for (String id : postAddDTO.getPermissionIds().split(",")) {
                PostPermission postPermission = new PostPermission();
                postPermission.setPostId(post.getId());
                postPermission.setPermissionId(id);
                postPermissionList.add(postPermission);
            }
            try {
                postPermissionService.insertBatch(postPermissionList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("添加岗位权限失败!");
            }
        }

        return new Resp<String>().success("添加岗位成功!");
    }

    /**
     * 根据条件查询岗位列表
     *
     * @param
     * @param
     * @param postName
     * @return
     */
    @Override
    @CommonService
    public PageResult<PostListVO> findPostListByCondition(Integer pageNum, Integer pageSize, String postName) throws DataIsEmptyException {
        if (pageNum == null) {
            List<PostListVO> list = postMapper.findPostListByCondition(postName);
            if (CollUtil.isEmpty(list)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<>(list);
        } else {
            Page<Post> page = new Page<>(pageNum, pageSize);
            List<PostListVO> list = postMapper.findPostListByCondition(postName, page);
            if (CollUtil.isEmpty(list)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<>(list);
        }
    }

    /**
     * 根据岗位主键id查询岗位详情
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    public Resp findPostDetailsById(String id) throws DataIsEmptyException {

        PostDetailsVO postDetailsVO = postMapper.findPostDetailsById(id);

        if (StringUtils.isEmpty(postDetailsVO)) {
            throw new DataIsEmptyException();
        }

        //权限
        List<PermissionVO> permissionVOList = permissionService.findPermissionList(id);
        postDetailsVO.setPermissionVOList(permissionVOList);

        List<PostPermission> permissions = postPermissionMapper.selectList(new EntityWrapper<PostPermission>().eq("post_id", id));
        String ids = "";
        for(int i = 0; i < permissions.size(); i++){
            ids += permissions.get(i).getPermissionId() + ",";
        }
        postDetailsVO.setPermissionIds(ids);

        return new Resp<PostDetailsVO>().success(postDetailsVO);
    }

    /**
     * 根据岗位主键id编辑岗位
     *
     * @param postUpdateDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp updatePostDetailsById(PostUpdateDTO postUpdateDTO) throws BusinessException {

        Post post = new Post();
        BeanUtils.copyProperties(postUpdateDTO, post);

        try {
            updateById(post);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("修改岗位失败!");
        }

        postPermissionMapper.delete(new EntityWrapper<PostPermission>().eq("is_deleted", Constant.IS_DELETE_NO).eq("post_id", post.getId()));

        if (!StringUtils.isEmpty(postUpdateDTO.getPermissionIds())) {
            List<PostPermission> permissionList = new ArrayList<>();
            for (String id : postUpdateDTO.getPermissionIds().split(",")) {
                if(id.equals("0")){
                    continue;
                }
                PostPermission postPermission = new PostPermission();
                postPermission.setPostId(post.getId());
                postPermission.setPermissionId(id);
                permissionList.add(postPermission);
            }
            try {
                postPermissionService.insertBatch(permissionList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("修改岗位权限失败!");
            }
        }

        return new Resp<String>().success("修改岗位成功!");
    }

    /**
     * 根据岗位主键id删除岗位
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp deletePostDetailsById(String id) throws DataIsEmptyException, BusinessException {

        Post post = selectById(id);

        if (StringUtils.isEmpty(post)) {
            throw new DataIsEmptyException();
        }

        //判断是否还有员工存在于该岗位
        List<User> userList = userService.selectList(new EntityWrapper<User>().eq("is_deleted", Constant.IS_DELETE_NO).eq("post_id", post.getId()));
        if (CollUtil.isNotEmpty(userList)) {
            throw new BusinessException("该岗位还存在员工!");
        }

        //删除岗位权限中间表数据
        List<PostPermission> postPermissionList = postPermissionMapper.selectList(new EntityWrapper<PostPermission>().eq("is_deleted", Constant.IS_DELETE_NO)
                .eq("post_id", post.getId()));
        if (CollUtil.isNotEmpty(postPermissionList)) {
            postPermissionList.forEach(x -> {
                postPermissionMapper.deleteById(x.getId());
            });
        }


        post.setIsDeleted(1);
        try {
            updateById(post);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("删除岗位失败!");
        }

        return new Resp<String>().success("删除岗位成功!");
    }

    @Override
    public PageResult<PostListVO> findPostList(PostListDTO<PostListVO> postListDTO) {
        Page<PostListVO> page = postListDTO.getPage();
        if(page != null){
            return new PageResult<>(postMapper.findPostList(page, postListDTO), page.getPages());
        }
        return new PageResult<>(postMapper.findPostList(postListDTO));
    }


    /**
     * 处理权限数据
     *
     * @param permissionVOList
     * @return
     */
    public List<PermissionVO> processPermission(List<PermissionVO> permissionVOList) {

        //最终的返回集合
        List<PermissionVO> permissionVOSEnd = new ArrayList<>();

        List<PermissionVO> permissionVOSAll = new ArrayList<>();
        List<Permission> permissionList = permissionMapper.selectList(new EntityWrapper<Permission>().eq("is_deleted", Constant.IS_DELETE_NO));

        if (CollUtil.isNotEmpty(permissionList)) {
            permissionList.forEach(x -> {
                PermissionVO permissionVO = new PermissionVO();
                BeanUtils.copyProperties(x, permissionVO);
                permissionVOSAll.add(permissionVO);
            });
        }

        permissionVOSAll.forEach(x -> {
            if ("0".equals(x.getPId())) {
                PermissionVO permissionVO = new PermissionVO();
                BeanUtils.copyProperties(x, permissionVO);
                permissionVO.setIsHave("2");//初始化值
                //判断是否存在权限值
                if (CollUtil.isNotEmpty(permissionVOList)) {
                    permissionVOList.forEach(p -> {
                        if (x.getId().equals(p.getId())) {
                            permissionVO.setIsHave("1");//赋值
                        }
                    });
                }
                permissionVOSEnd.add(permissionVO);
            }
        });

        permissionVOSEnd.forEach(x -> {
            List<PermissionVO> permissionVOS = new ArrayList<>();
            List<PermissionVO> childPermissionVO = getChildPermission(x.getId(), permissionVOList, permissionVOSAll);
            if (CollUtil.isNotEmpty(childPermissionVO)) {
                permissionVOS.addAll(childPermissionVO);
            }
            x.setPermissionVOList(permissionVOS);
        });


        return permissionVOSEnd;
    }

    /**
     * 递归查询子权限集合
     *
     * @param id
     * @param permissionVOList
     * @return
     */
    public List<PermissionVO> getChildPermission(String id, List<PermissionVO> permissionVOList, List<PermissionVO> permissionVOAll) {

        List<PermissionVO> childPermissionList = new ArrayList<>();

        permissionVOAll.forEach(x -> {
            if (!"0".equals(x.getPId())) {
                if (x.getPId().equals(id)) {
                    x.setIsHave("2");//初始化值
                    if (CollUtil.isNotEmpty(permissionVOList)) {
                        permissionVOList.forEach(p -> {
                            if (x.getId().equals(p.getId())) {
                                x.setIsHave("1");
                            }
                        });
                    }
                    childPermissionList.add(x);
                }
            }
        });

        childPermissionList.forEach(x -> {
            List<PermissionVO> permissionVOS = new ArrayList<>();
            List<PermissionVO> childPermissionVO = getChildPermission(x.getId(), permissionVOList, permissionVOAll);
            if (CollUtil.isNotEmpty(childPermissionVO)) {
                permissionVOS.addAll(childPermissionVO);
            }
            x.setPermissionVOList(permissionVOS);
        });

        if (childPermissionList.size() == 0) {
            return null;
        }

        return childPermissionList;
    }

}
